#!/usr/bin/env python
# -*- coding:utf8 -*-
import datetime
import sys
from flask import abort,request,render_template,jsonify,flash,redirect,url_for
from . import clips
from .models import Tag,Item,Category,TagUrl
from .schemas import TagSchema,TagUrlSchema
from .forms import ItemEditForm,TagEditForm,TagUrlEditForm
from flask_login import login_user,logout_user,login_required,current_user
from .. import db,login_manager
from sqlalchemy import func, or_, not_
from .decorators import json_safe
#import uuid

#TODO: WHY WHY WHY can be set in app?
default_encoding = 'utf-8'
if sys.getdefaultencoding() != default_encoding:
    reload(sys)
    sys.setdefaultencoding(default_encoding)

def __basedata(route=None):
    data = {}
    data['title'] = "cmd"
    data['theme'] = "default"
    data['base_url'] = "%s/clips/" % data["theme"] 
    #print sys._getframe().f_code.co_name
    if not route:
        route=sys._getframe().f_back.f_code.co_name
    data['path'] = data['base_url'] + route + ".html"
    data['curr_user'] = current_user
    return data

#方法名约定同模板名相同还是要谨慎:但是当前可以用__basedata(route)的形式覆盖
#如果换模板也需要换方法,模板上url_for会用到方法名,不如render_template灵活
def __render(data):
    return render_template(data['path'],data=data)

@clips.route('/')
def index():
    data = __basedata()
    rows = db.session.query(Item).\
            filter(Item.status==0).\
            order_by(Item.modified_time.desc()).limit(10).all()
    data['rows'] = rows 
    print data
    return render_template(data['path'],data=data)

@clips.route('/item_list')
def item_list():
    data = __basedata()
    rows = db.session.query(Item).\
            filter(Item.status==0).\
            order_by(Item.modified_time.desc()).limit(10).all()
    data['rows'] = rows
    return __render(data)

@clips.route('/item_edit/<int:id>',methods=['GET','POST'])
@clips.route('/item_edit',methods=['GET','POST'])
@login_required
def item_edit(id=0):
    if id>0:
        p = db.session.query(Item).get(id)
        #item = Item.query.filter_by(id=id).first()
        #print item
        form = ItemEditForm(obj=p) #auto binding
    else:
        form = ItemEditForm()
        p = Item()
        p.create_by = current_user.name
        p.create_time = datetime.datetime.now()
        p.status = 0
        p.votes= 0
        p.devotes = 0
    form.category_id.choices =  [(g.id, g.category_name) for g in Category.query.order_by('category_name')]
    data = __basedata() 
    data['form'] = form
    if form.validate_on_submit():
        print "saving..."
        #p.id =str(uuid.uuid1())
        p.title = form.title.data
        p.content = form.content.data
        p.category_id = form.category_id.data 
        p.readme = form.readme.data
        p.modified_by = current_user.name
        p.modified_time = datetime.datetime.now()
        p.owner = current_user.name
        db.session.add(p)
        db.session.commit()
        return redirect(url_for("clips.item_list"))
    return render_template(data['path'],data=data)

@clips.route('/item_remove/<int:id>',methods=['GET','POST'])
def item_remove(id):
    if id>0:
        p = db.session.query(Item).get(id)
        db.session.delete(p)
        db.session.commit()
        flash("Item removed!","success")
    else:
        abort(403)
    return redirect(url_for("clips.item_list",id=id));

#返回一个part页面 并根据tag的关键字过滤 反正不多,可本地过滤
@clips.route('/item_tags_pool/<int:itemid>')
def item_tags_pool(itemid):
    data = __basedata() 
    one = db.session.query(Item).get(itemid)
    alltags = db.session.query(Tag).all()
    #load current tags & other tags / with filters on heading
    data['tags'] = one.tags
    #data['alltags'] = alltags # not elegent for other so let all in 
    data['othertags'] = set(alltags) - set(one.tags)
    data['item'] = one
    #if form.validate_on_submit():

    return render_template(data['path'],data=data)

#JSON 用于在item_tags_pool的part页面上操作的ajax
@clips.route('/item_tags/<int:id>/<int:tagid>/<string:action>',methods=['GET','POST'])
def item_tags_stick(id,tagid,action):
    @json_safe()
    def work():
        if id>0:
            p = db.session.query(Item).get(id)
            tag = db.session.query(Tag).get(tagid)
            if action == "on":
                p.tags.append(tag)
            else:
                p.tags.remove(tag)
            db.session.commit()
        else:
            raise Exception("invalid id")
    result = work() 
    return result

#JSON 当前没用
@clips.route('/item_tags/<int:itemid>')
def item_tags(itemid):
    data={}
    one = db.session.query(Item).get(itemid)
    tags = one.tags

    """cl = db.session.query(Tags).\
            filter(Tag.status==0,Tag.id==id).\
            order_by(Tag.id).all()
            """
    sc = TagSchema(many=True)
    data['data'] = sc.dump(tags).data
    print data['data']
    return jsonify(data)

#JSON 数据
@clips.route('/tagurls/<int:tagid>.json',methods=['GET','POST'])
def tag_urls(tagid):
    data={}
    print tagid
    tag = db.session.query(Tag).get(tagid)
    urls = tag.urls

    sc = TagUrlSchema(many=True)
    data['data'] = sc.dump(urls).data
    data["success"] = True
    #json.dumps(t,ensure_ascii=False)
    print data['data']
    return jsonify(data)

@clips.route('/tag_list')
def tag_list():
    data = __basedata("tag_list")
    rows = db.session.query(Tag).\
            filter(Tag.status==0).\
            order_by(Tag.name.desc()).limit(20).all()
    data['rows'] = rows
    print data
    return render_template(data['path'],data=data)

@clips.route('/tag_edit/<int:id>',methods=['GET','POST'])
@clips.route('/tag_edit',methods=['GET','POST'])
@login_required
def tag_edit(id=0):
    data = __basedata() 
    form = TagEditForm()
    if id>0:
        p = db.session.query(Tag).get(id)
        form = TagEditForm(obj=p) #auto binding
    else:
        p = Tag()
    if form.validate_on_submit():
        print "saving..."
        p.name = form.name.data
        p.content = form.content.data
        db.session.add(p)
        db.session.commit()
        return redirect(url_for("clips.tag_list"))
    data['form'] = form
    data['tag'] = p
    return render_template(data['path'],data=data)

#非JSON版本
@clips.route('/tagurl/remove/<int:id>',methods=['GET','POST'])
def tagurl_remove(id):
    if id>0:
        p = db.session.query(TagUrl).get(id)
        tagid = p.tag.id
        db.session.delete(p)
        db.session.commit()
        flash("Link removed!","success")
    else:
        abort(403)
    return redirect(url_for("clips.tag_edit",id=tagid));

#JSON
@clips.route('/tagurl/delete/<int:id>',methods=['GET','POST'])
def tagurl_delete(id):
    @json_safe()
    def work():
        if id>0:
            p = db.session.query(TagUrl).get(id)
            count=len(p.tag.urls)
            #print type(p.tag.urls)
            print "----%s" % count
            #uselist=False on backref?
            db.session.delete(p)
            db.session.commit()
            return count-1
        else:
            raise Exception("invalid id")
    result = work() 
    return result

#需要共享view时候 怎么办 这样不好看
#@clips.route('/tag/<int:tagid>/url_edit/<int:id>',methods=['GET','POST'])
#@clips.route('/tag/<int:tagid>/url_edit',methods=['GET','POST'])

@clips.route('/tagurl/edit/<int:id>',methods=['GET','POST'])
@clips.route('/tagurl/add/<int:tagid>',methods=['GET','POST'])
@login_required
def tagurl_edit(id=0,tagid=0):
    data = __basedata() 
    #form = TagUrlEditForm()
    if id>0:
        p = db.session.query(TagUrl).get(id)
        data['tag'] = p.tag
        form = TagUrlEditForm(obj=p) #auto binding
        print id
    elif tagid>0:
        tag = db.session.query(Tag).get(tagid) #just a validate
        data['tag'] = tag
        p = TagUrl()
        p.tag_id = tagid
        p.url = "http://";
        form = TagUrlEditForm(obj=p) #auto binding
        #tag.urls.append(p)
        #p.tag = tag #auto commit?
        print tagid
    else:
        return redirect(url_for("clips.tag_list"))

    if form.validate_on_submit():
        print "saving..."
        p.title = form.title.data
        p.url = form.url.data
        db.session.add(p)
        db.session.commit()
        return redirect(url_for("clips.tag_edit",id=p.tag_id))
    data['form'] = form
    return render_template(data['path'],data=data)

#当前没用 可用于查看某个item_view详情
@clips.route('/item/<string:pid>')
def item(pid):
    data = __basedata() 
    p = db.session.query(Item).\
            filter(Item.status==1,Item.id==pid).first()
    print p
    if p:
        data['item'] = p
    print data
    return render_template(data['path'],data=data)

